package com.fingard.dsp.bank.directbank.gfgs01;

import java.sql.Connection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.directbank.fngrd01.util.StringHelper;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;


/**
 * Created by F on 2018/11/26.
 * 付款，付款状态查询
 */
public class GFGS01SinglePay extends GFGS01Base implements ISinglePay{

    private static final String INSERTSEQ = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,TRANSDATE,REQSEQID,BANKREQSEQID) values (?,?,?,?,?);";
    private static final String SELECTSEQ = "SELECT BANKREQSEQID FROM REQSEQIDMAPPING WHERE REQSEQID=?;";

    /**
     * 单笔转账
     * @param p_req1908
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception{
        RetAtsSingle retAtsSingle = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        Connection conn= FGBiz.getLocalDbConn();
        try{
            //非公有参数
            XmlTextWriter xmlWriter = new XmlTextWriter();
            //拼接请求报文头
            GFGS01Header header=new GFGS01Header();
            header.billType="payment";//交易码
            header.roottag="paybill";
            header.wsdlMethod="doPay";//提供webservice接口，接收外部付款单据
            writeCommonHeader(xmlWriter,header);
            //拼接请求报文体
            XElement body = new XElement("paybill","");
            String seqNo=getQryTransID();
            String bankSeqId=seqNo;//客户交易流水号
            body.addChild(new XElement("busino",bankSeqId));//客户交易流水号
            body.addChild(new XElement("payacc",p_req1908.singleDetail.payAct));//付款账号
            if(!StringHelper.isNullOrEmpty(getBankConfig().getValueAsString("customerName"))
                    && getBankConfig().getValueAsString("customerName").equals(p_req1908.singleDetail.cnapsName)
                    && getBankConfig().getValueAsString("customerName").equals(p_req1908.singleDetail.payBankLocation)){
                body.addChild(new XElement("paytype","1"));//付款类型
            }else {
                body.addChild(new XElement("paytype",p_req1908.singleDetail.innerPay));//付款类型
            }
            body.addChild(new XElement("recacc",p_req1908.singleDetail.recAct));//收款账号
            body.addChild(new XElement("recname",p_req1908.singleDetail.recName));//收款账户名称
            body.addChild(new XElement("recbank",p_req1908.singleDetail.cnapsName));//收款银行开户行
            body.addChild(new XElement("banktype",getBankType(p_req1908.singleDetail.cnapsName)));//收款银行类别
            body.addChild(new XElement("bankcode",p_req1908.singleDetail.cnapsCode));//人行联行号
            String areaName=p_req1908.singleDetail.recAreaName;
            if(!"".equals(areaName)){
                body.addChild(new XElement("recpvc",areaName.substring(0,areaName.indexOf("_"))));//汇入省
                body.addChild(new XElement("reccity",areaName.substring(areaName.indexOf("_")+1)));//汇入市
            }else {
                detail.respCode = "-1";
                detail.respInfo = "收方区域名称不能为空";
                WriteBankLogLn("收方区域名称不能为空");
                retAtsSingle.writeRetDetail(detail);
                return retAtsSingle;
            }
            body.addChild(new XElement("urgent",p_req1908.singleDetail.paySpd));//汇款速度 0普通 1加急
            body.addChild(new XElement("amt",p_req1908.singleDetail.payAmount));//付款金额
            body.addChild(new XElement("cur",convertCurToBank(p_req1908.singleDetail.payCur)));//币种
            String usage=p_req1908.singleDetail.purpose;//用途
            String length=getBankConfig().getValueAsString("usageLength").replaceAll(" ","");//配置截取的长度
            if(!StringHelper.isNullOrEmpty(length)){
                if(!StringHelper.isNullOrEmpty(usage) && usage.length()>Integer.parseInt(length)){
                    usage=usage.substring(0,Integer.parseInt(length));
                }
            }
            body.addChild(new XElement("usage",usage));//用途
            body.addChild(new XElement("applydate", Format.Date10Format.format(new Date())));//申请付款日期
            //获取签名
            StringBuilder sb=new StringBuilder();
            boolean flag=getSignedData(seqNo+p_req1908.singleDetail.payAct
                    +p_req1908.singleDetail.recAct+p_req1908.singleDetail.recName+p_req1908.singleDetail.payAmount,sb);
            if(flag) {
                body.addChild(new XElement("signlen", String.valueOf(sb.toString().trim().getBytes().length)));//签名数据长度
                body.addChild(new XElement("signdata", sb.toString().trim()));//签名数据
                nodeAnalysis(p_req1908.singleDetail.srcXElement, body, getCharset());
                xmlWriter.writeXElement(body);
                xmlWriter.writeEndDocument();
                //记录ats支付流水号对应的银行支付流水号，供查询状态接口使用
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1908.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1908.singleDetail.askNumber, bankSeqId});
                //发送请求报文
                String[] bankResult = sendToBank(xmlWriter.toXmlString(),header);

                //处理响应报文
                if (bankResult[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1].trim(), tmpSbMsg);
                    if (tmpBkReader != null) {
                        String returnCode = tmpBkReader.getFirstText("/ufinterface/sendresult/retcode");//响应码
                        String returnMsg = tmpBkReader.getFirstText("/ufinterface/sendresult/retmemo");//响应消息
                        detail.respCode = "0";
                        detail.respInfo = returnMsg;
                        detail.reqSeqID = p_req1908.singleDetail.askNumber;//流水号
                        detail.payInfoCode = returnCode;
                        detail.transState = detail.payInfoCode;
                        detail.transAmt = "";//交易金额
                        detail.outTransID = tmpBkReader.getFirstText("/ufinterface/sendresult/busino");
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbMsg.toString();
                    }
                } else if (bankResult[0].equals(ConnState.FAIL)) {
                    detail.respCode = "0";
                    detail.respInfo = bankResult[1];
                    detail.reqSeqID = p_req1908.singleDetail.askNumber;
                    detail.transState = PaymentState.FAIL_Payment;
                    detail.payInfoCode = bankResult[0];
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = bankResult[1];
                    detail.reqSeqID = p_req1908.singleDetail.askNumber;
                }
            }else {
                detail.respCode = "-1";
                detail.respInfo = sb.toString();
                detail.reqSeqID = p_req1908.singleDetail.askNumber;
            }
        }catch (Exception e){
            detail.respCode = "-1";
            detail.respInfo = e.getMessage();
            e.printStackTrace();
            WriteBankLogLn("付款出现异常:"+e);
        }finally {
            conn.close();
        }
        retAtsSingle.writeRetDetail(detail);
        return retAtsSingle;
    }

    /**
     * 单笔转账状态查看
     * @param p_req1944
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception{
        RetAtsSingle retAtsSingle = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        Connection conn=FGBiz.getLocalDbConn();
        try{
            //非公有参数
            XmlTextWriter xmlTextWriter = new XmlTextWriter();
            //拼接请求报文头
            GFGS01Header header=new GFGS01Header();
            header.billType="payquery";//交易码
            header.roottag="paybill";
            header.wsdlMethod="queryPay";//提供webservice接口，查询付款单据支付状态
            writeCommonHeader(xmlTextWriter,header);
            //拼接请求报文体
            XElement body = new XElement("paybill","");
            if(p_req1944.askNumber.isEmpty()){
                detail.respCode ="-1";
                detail.respInfo = "财务系统交易流水号不能为空";
            }else {
                Map<String, Object> selMap=JDBCHelper.execQuerySingle(conn,SELECTSEQ,new Object[]{p_req1944.askNumber});
                if(selMap.size()>0){
                    body.addChild(new XElement("busino", selMap.get("BANKREQSEQID").toString()));//财务系统交易流水号
                }else {
                    detail.respCode ="-1";
                    detail.respInfo = "财务系统交易流水号关联映射异常，请检查";
                    retAtsSingle.writeRetDetail(detail);
                    return retAtsSingle;
                }
                body.addChild(new XElement("payacc", p_req1944.payAct));//付款帐号
                xmlTextWriter.writeXElement(body);
                xmlTextWriter.writeEndDocument();
                //发送请求报文
                String[] bankResult = sendToBank(xmlTextWriter.toXmlString(),header);

                //处理响应报文
                if (bankResult[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader xmlSbReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                    if (xmlSbReader != null) {
                        String rsp_no = xmlSbReader.getFirstText("/ufinterface/sendresult/retcode");//响应码
                        String rsp_msg = xmlSbReader.getFirstText("/ufinterface/sendresult/retmemo");//响应信息
                        detail.respCode = "0";//响应码
                        detail.respInfo = rsp_msg;//响应结果
                        detail.reqSeqID = p_req1944.askNumber;//交易流水号
                        detail.payInfoCode = rsp_no;//交易结果
                        detail.transState = detail.payInfoCode;
                    }else {
                        detail.respCode = "-1";
                        detail.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    detail.respCode = "-1";
                    detail.respInfo = bankResult[1];
                }
            }
        }catch (Exception e){
            detail.respCode = "-1";
            detail.respInfo = e.getMessage();
            e.printStackTrace();
            WriteBankLogLn("查询付款状态异常："+e);
        }finally {
            conn.close();
        }
        retAtsSingle.writeRetDetail(detail);
        return retAtsSingle;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception{
        return  null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception{
        return  null;
    }
}
